import { Component, OnInit, AfterViewInit, ChangeDetectorRef, OnChanges, Input, Output, EventEmitter, ViewChild, forwardRef, SimpleChanges } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NzFormatEmitEvent, NzTreeComponent, NzTreeNodeOptions } from 'ng-zorro-antd/tree';
import { NzMessageService } from 'ng-zorro-antd/message';
import { SecondCouponService } from '../../../../used-store/used-marketing-manage/services/second-coupon.service';

@Component({
  selector: 'model-select-tree',
  templateUrl: './model-select-tree.component.html',
  styleUrls: ['./model-select-tree.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ModelSelectTreeComponent),
      multi: true
    }
  ]
})
export class ModelSelectTreeComponent implements ControlValueAccessor, OnInit, AfterViewInit, OnChanges {
  @ViewChild('nzTreeComponent', { static: false }) nzTreeComponent!: NzTreeComponent;

  @Input() defaultKeys!: Array<any>;
  @Input() disabled: boolean = false;
  @Output() onSubmit = new EventEmitter();

  isVisible = false;
  _onChange: any = () => {};
  treeLoading = false;
  searchValue = '';

  defaultCheckedKeys: any[] = [];
  defaultExpandedKeys: any[] = [];
  nodes: NzTreeNodeOptions[] = [];

  constructor(
    private message: NzMessageService,
    public changeDetectorRef: ChangeDetectorRef,
    private services: SecondCouponService
  ) { }

  ngOnInit(): void {
  }

  ngOnChanges(changes: SimpleChanges): void {
    // this.defaultCheckedKeys = this.defaultKeys;
  }

  ngAfterViewInit(): void {
    // this.changeDetectorRef.detectChanges();
  }

  // loadTree
  async loadTreeData() {
    this.searchValue = '';
    this.nodes = [];
    this.defaultExpandedKeys = [];

    this.treeLoading = true;
    const res: any = await this.services.getBrandClassifyData();
    this.treeLoading = false;
    
    if (res.code === 0) {
      this.nodes = this.combinationTreeData(res.data);
      this.defaultCheckedKeys = this.defaultKeys;
      this.defaultExpandedKeys = this.getExpandedData(res.data, this.defaultExpandedKeys);
    } else {
      this.message.error(res.message);
    }
  }

  combinationTreeData(arrs: any[]) {
    if (arrs.length) {
      arrs.forEach((item: any) => {
        if (item.children && item.children?.length) {
          this.combinationTreeData(item.children);
        }

        item.key = item.id;
        item.title = item.name;
        item.disableCheckbox = this.disabled;

        if (!item.children || !item.children.length) {
          item.isLeaf = true;
        }
      })
    }
    return arrs;
  }

  getExpandedData(arrs: any[], result: any[]) {
    if (arrs.length) {
      arrs.forEach((item: any) => {
        if (item.children && item.children?.length) {
          this.getExpandedData(item.children, result);
          return
        }

        if (
          this.defaultKeys.includes(item.key)
        ) {
          result.push(item.brandId, item.seriesId);
        }
      })
    }
    return Array.from(new Set(result));
  }

  /**
   * ----------------------------------------------------------------
   * Tree
   * ----------------------------------------------------------------
   */
  nzCheck(event: NzFormatEmitEvent): void {}

  nzEvent(event: NzFormatEmitEvent): void {
    if (this.searchValue === '') {
      this.loadTreeData();
    }
  }

  submitTreeData() {
    let selectTreeNode = this.nzTreeComponent.getCheckedNodeList();
    let tempObj: any = {
      brandList: [],
      seriesList: [],
      modelList: []
    };

    tempObj = this.mergeArrs(selectTreeNode, tempObj);
    this.handleCancel();
    this.onSubmit.emit(tempObj);
  }

  mergeArrs(arrs: any[], obj: any) {
    arrs.forEach((ele: any) => {
      if (ele._children && ele._children.length > 0) {
        this.mergeArrs(ele._children, obj);
      }

      switch (ele.level) {
        case 0:
          obj.brandList.push(ele.key);
          break;
        case 1:
          obj.seriesList.push(ele.key);
          break;
        case 2:
          obj.modelList.push(ele.key);
          break;
      }
    })
    return obj;
  }

  /**
   * ----------------------------------------------------------------
   * ngModal
   * ----------------------------------------------------------------
   */
  handleCancel() {
    this.isVisible = false;
    this._onChange(this.isVisible);
  }

  writeValue(val: any) {
    if (val) {
      this.defaultKeys = this.defaultKeys.map((m: any) => +m);
      this.loadTreeData();
    }
    this.isVisible = val;
  }

  registerOnChange(fn: (_: any) => void): void {
    this._onChange = fn;
  }

  registerOnTouched(fn: any): void {}
}
